package com.xinqi.modules.chat.chat.group.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.base.response.R;
import com.xinqi.common.base.user.Account;
import com.xinqi.common.core.constant.ChatConstants;
import com.xinqi.common.core.constant.ConfigKeyConstants;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.core.utils.StringUtils;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.modules.chat.chat.group.convert.ChatGroupUserConvert;
import com.xinqi.modules.chat.chat.group.domain.ChatGroupEntity;
import com.xinqi.modules.chat.chat.group.domain.ChatGroupUserEntity;
import com.xinqi.modules.chat.chat.group.dto.req.*;
import com.xinqi.modules.chat.chat.group.dto.rsp.ChatGroupUserAdminResultDTO;
import com.xinqi.modules.chat.chat.group.dto.rsp.ChatGroupUserResultDTO;
import com.xinqi.modules.chat.chat.group.mapper.ChatGroupMapper;
import com.xinqi.modules.chat.chat.group.mapper.ChatGroupUserMapper;
import com.xinqi.modules.chat.chat.group.service.ChatGroupUserService;
import com.xinqi.modules.chat.enums.group.*;
import com.xinqi.modules.chat.third.rongyun.service.RongyunService;
import com.xinqi.modules.chat.third.utils.ImageUtil;
import com.xinqi.modules.course.clazz.client.ClassStudentClient;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.course.course.enums.ClassStudentRelationshipEnum;
import com.xinqi.modules.sys.config.client.SysConfigClient;
import com.xinqi.modules.user.user.client.UserClient;
import com.xinqi.modules.user.user.dto.rsp.UserResultDTO;
import io.rong.util.CodeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 群组成员表服务层实现
 *
 * @author: system
 * @date: 2023/01/12
 */
@Service("chatGroupUserService")
@RequiredArgsConstructor
public class ChatGroupUserServiceImpl extends BaseServiceImpl<ChatGroupUserMapper, ChatGroupUserEntity> implements ChatGroupUserService {

    private final ChatGroupUserConvert chatGroupUserConvert;

    private final UserClient userClient;

    private final ChatGroupMapper chatGroupMapper;

    private final RongyunService rongyunService;

    private final ChatGroupMessageService chatGroupMessageService;

    private final ChatGroupMQService chatGroupMQService;

    private final SysConfigClient sysConfigClient;

    private final ClassStudentClient classStudentClient;


    /**
     * 根据群组ID删除群成员
     *
     * @param groupId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByGroupId(String groupId) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupId), MessageUtils.message("chat.chat.groupId.not.blank"));
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getGroupId, groupId);

        return this.remove(wrapper);
    }

    /**
     * 设置群-成员
     *
     * @param userId
     * @param dto    ChatGroupUserUpdateDTO
     * @return
     */
    @Override
    public Boolean setGroupUser(Long userId, ChatGroupUserUpdateDTO dto) {
        ChatGroupUserResultDTO old = Optional.ofNullable(this.baseMapper.selectByGroupIdAndUserId(dto.getGroupId(), userId, GroupUserStatusEnum.ONE.getCode()))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("data.does.not.exist")));
        //群备注、群昵称可设置为空
        LambdaUpdateWrapper<ChatGroupUserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(dto.getGroupRename() != null, ChatGroupUserEntity::getGroupRename, dto.getGroupRename())
            .set(dto.getRenames() != null, ChatGroupUserEntity::getRenames, dto.getRenames())
            .set(StringUtils.isNotEmpty(dto.getBackground()), ChatGroupUserEntity::getBackground, dto.getBackground())
            .set(Objects.nonNull(dto.getHiddenChat()), ChatGroupUserEntity::getHiddenChat, dto.getHiddenChat())
            .set(Objects.nonNull(dto.getShowMemberName()), ChatGroupUserEntity::getShowMemberName, dto.getShowMemberName())
            .set(StringUtils.isNotEmpty(dto.getFollow()), ChatGroupUserEntity::getFollow, dto.getFollow())
            .set(ChatGroupUserEntity::getGroupId, old.getGroupId());

        //免打扰
        if (Objects.nonNull(dto.getIsDisturb()) && !Objects.equals(old.getIsDisturb(), dto.getIsDisturb())) {
            if (Objects.equals(YesNoNumberEnum.YES.getCode(), dto.getIsDisturb())) {
                boolean muteFlag = rongyunService.conversationDisturb(userId.toString(), old.getGroupId(),
                    CodeUtil.ConversationType.GROUP, YesNoNumberEnum.YES.getCode());
                if (muteFlag) {
                    updateWrapper.set(ChatGroupUserEntity::getIsDisturb, dto.getIsDisturb());
                }
            } else if (Objects.equals(YesNoNumberEnum.NO.getCode(), dto.getIsDisturb())) {
                boolean unMuteFlag = rongyunService.conversationDisturb(userId.toString(), old.getGroupId(),
                    CodeUtil.ConversationType.GROUP, YesNoNumberEnum.NO.getCode());
                if (unMuteFlag) {
                    updateWrapper.set(ChatGroupUserEntity::getIsDisturb, dto.getIsDisturb());
                }
            }
        }
        //置顶
        if (Objects.nonNull(dto.getIsTop()) && !Objects.equals(old.getIsTop(), dto.getIsTop())) {
            if (Objects.equals(YesNoNumberEnum.YES.getCode(), dto.getIsTop())) {
                updateWrapper.set(ChatGroupUserEntity::getTopTime, LocalDateTime.now());
                boolean topFlag = rongyunService.conversationTop(userId.toString(), CodeUtil.ConversationType.GROUP.getName(),
                    old.getGroupId(), true);
                if (topFlag) {
                    updateWrapper.set(ChatGroupUserEntity::getIsTop, dto.getIsTop());
                }
            } else if (Objects.equals(YesNoNumberEnum.NO.getCode(), dto.getIsTop())) {
                updateWrapper.set(ChatGroupUserEntity::getTopTime, null);
                boolean unTopFlag = rongyunService.conversationTop(userId.toString(), CodeUtil.ConversationType.GROUP.getName(),
                    old.getGroupId(), false);
                if (unTopFlag) {
                    updateWrapper.set(ChatGroupUserEntity::getIsTop, dto.getIsTop());
                }
            }
        }
        updateWrapper.eq(ChatGroupUserEntity::getId, old.getId());
        return this.update(updateWrapper);
    }

    /**
     * 添加邀请群成员
     *
     * @param groupId 群组Id（融云）
     * @param dto     AddUserGroupCreateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addGroupUser(Account user, String groupId, AddUserGroupCreateDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupId), MessageUtils.message("chat.chat.groupId.not.blank"));
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(groupId)))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getGroupUserIds()), MessageUtils.message("chat.group.user.add.user.not.blank"));
        //群成员上限300人
        Long groupUserCount = this.selectCountGroupUser(groupId);
        if (Objects.nonNull(groupUserCount) && groupUserCount >= ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
        }
        //获取需要添加的用户列表
        List<UserResultDTO> userList = CollectionUtil.isNotEmpty(dto.getGroupUserIds()) ? R.as(userClient.findList(dto.getGroupUserIds())) : new ArrayList<>();
        //添加群成员列表
        this.addUserGroup(user, userList, group, user.getId(), groupUserCount);

        if (Objects.nonNull(groupUserCount) && ChatConstants.CHAT_GROUP_AVATAR_COUNT > groupUserCount) {
            //生成新头像
            initGroupAvatar(group.getGroupId());
        }

        return Boolean.TRUE;
    }

    /**
     * 添加群成员
     *
     * @param user
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addAdmin(Account user, AddUserGroupCreateAdminDTO dto) {
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getMobileList()), MessageUtils.message("chat.group.user.add.user.not.blank"));
        List<UserResultDTO> userList = R.as(userClient.findByMobile(dto.getMobileList()));

        // 判断是否添加用户已注册
        if (dto.getMobileList().size() == 1) {
            CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(userList), MessageUtils.message("chat.group.user.add.user.not.register"));
        } else {
            CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(userList), MessageUtils.message("chat.group.user.add.more.user.not.register"));
        }

        if (CollectionUtil.isEmpty(dto.getMobileList())) {
            return Boolean.TRUE;
        }
        //查询群组内已入群成员与待审核成员（审核不通过的成员可以再次发起申请）
        List<ChatGroupUserEntity> userEntityList = this.list(userWrapper(dto.getGroupId(), Arrays.asList(GroupUserStatusEnum.ONE.getCode(), GroupUserStatusEnum.ZERO.getCode())));
        Map<Long, ChatGroupUserEntity> map = new HashMap<>();
        userEntityList.forEach(item -> {
            map.put(item.getUserId(), item);
        });
        //新加入成员
        List<ChatGroupUserEntity> addUserList = new ArrayList<>();
        //已申请待审核可直接入群成员
        List<ChatGroupUserEntity> updateUserList = new ArrayList<>();
        //小灰条消息成员
        List<UserResultDTO> userResultList = new ArrayList<>();

        userList.forEach(item -> {
            if (map.containsKey(item.getId())) {
                ChatGroupUserEntity userEntity = map.get(item.getId());
                if (Objects.equals(GroupUserStatusEnum.ZERO.getCode(), userEntity.getStatus())) {
                    ChatGroupUserEntity update = chatGroupUserConvert.newEntity(userEntity);
                    update.setCommon(GroupUserCommonEnum.ADMIN.getCode());
                    update.setStatus(GroupUserStatusEnum.ONE.getCode());

                    userResultList.add(item);
                    updateUserList.add(update);
                }
            } else {
                ChatGroupUserEntity add = new ChatGroupUserEntity(dto.getGroupId(), item.getId(), "", "", "", "");
                add.setCommon(GroupUserCommonEnum.ADMIN.getCode());
                add.setStatus(GroupUserStatusEnum.ONE.getCode());
                userResultList.add(item);

                addUserList.add(add);
            }
        });

        // 判断用户是否已经加入群聊
        if (dto.getMobileList().size() == 1) {
            if (Objects.equals(YesNoNumberEnum.YES.getCode(), addUserList.get(0).getStatus())) {
                CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(addUserList), MessageUtils.message("chat.group.user.add.user.in.group.valid"));
            } else {
                CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(addUserList), MessageUtils.message("chat.group.user.add.user.in.group.apply.valid"));
            }
        }

        if (CollectionUtil.isNotEmpty(userResultList)) {
            //融云加群
            List<String> userIds = userResultList.stream().map(item -> Convert.toStr(item.getId())).collect(Collectors.toList());
            chatGroupMQService.sendAddMessage(group, userIds);
            //群若是禁言
            if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                //融云添加禁言
                chatGroupMQService.sendProhibitionMessage(group, userIds);
            }
            //添加群成员小灰条通知消息
            chatGroupMessageService.sendAddMessage(user, userResultList, group.getGroupId());
        }

        if (CollectionUtil.isNotEmpty(addUserList)) {
            this.saveBatch(addUserList);
        }
        if (CollectionUtil.isNotEmpty(updateUserList)) {
            this.updateBatchById(updateUserList);
        }
        return Boolean.TRUE;
    }

    /**
     * 获取需要加群的用户列表
     *
     * @param userList
     * @param group
     * @param operationUserId
     * @return
     */
    private void addUserGroup(Account user, List<UserResultDTO> userList, ChatGroupEntity group, Long operationUserId, Long groupUserCount) {
        if (CollectionUtil.isEmpty(userList)) {
            return;
        }
        //操作人权限校验
        ChatGroupUserResultDTO operationUser = selectByUserIdAndGroupId(operationUserId, group.getGroupId());
        boolean jurisdiction = Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), operationUser.getLeaderFlag())
            || Objects.equals(GroupUserLeaderFlagEnum.TWO.getCode(), operationUser.getLeaderFlag());

        //查询群组内已入群成员与待审核成员（审核不通过的成员可以再次发起申请）
        List<ChatGroupUserEntity> userEntityList = this.list(userWrapper(group.getGroupId(), Arrays.asList(GroupUserStatusEnum.ONE.getCode(), GroupUserStatusEnum.ZERO.getCode())));
        Map<Long, ChatGroupUserEntity> map = new HashMap<>();
        userEntityList.forEach(item -> {
            map.put(item.getUserId(), item);
        });
        //新加入成员
        List<ChatGroupUserEntity> addUserList = new ArrayList<>();
        //已申请待审核可直接入群成员
        List<ChatGroupUserEntity> updateUserList = new ArrayList<>();
        //小灰条消息成员
        List<UserResultDTO> userResultList = new ArrayList<>();
        //是否可直接入群
        boolean check = jurisdiction || Objects.equals(GroupExamineEnum.ZERO.getCode(), group.getExamine());
        userList.forEach(item -> {
            if (map.containsKey(item.getId())) {
                ChatGroupUserEntity userEntity = map.get(item.getId());
                if (check && Objects.equals(GroupUserStatusEnum.ZERO.getCode(), userEntity.getStatus())) {
                    ChatGroupUserEntity update = chatGroupUserConvert.newEntity(userEntity);
                    update.setStatus(GroupUserStatusEnum.ONE.getCode());

                    userResultList.add(item);
                    updateUserList.add(update);
                }
            } else {
                ChatGroupUserEntity add = new ChatGroupUserEntity(group.getGroupId(), item.getId(), "", "", "", "");
                add.setCommon(GroupUserCommonEnum.UNKNOWN.getCode());
                if (check) {
                    add.setStatus(GroupUserStatusEnum.ONE.getCode());
                    userResultList.add(item);
                } else {
                    add.setStatus(GroupUserStatusEnum.ZERO.getCode());
                }
                addUserList.add(add);
            }
        });

        //群成员上限300人
        long afterCount = groupUserCount + userResultList.size();
        if (afterCount > ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
        }

        if (CollectionUtil.isNotEmpty(userResultList)) {
            //融云加群
            List<String> userIds = userResultList.stream().map(item -> Convert.toStr(item.getId())).collect(Collectors.toList());
            chatGroupMQService.sendAddMessage(group, userIds);
            //群若是禁言
            if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                //融云添加禁言
                chatGroupMQService.sendProhibitionMessage(group, userIds);
            }
            //添加群成员小灰条通知消息
            chatGroupMessageService.sendAddMessage(user, userResultList, group.getGroupId());
        }

        if (CollectionUtil.isNotEmpty(addUserList)) {
            this.saveBatch(addUserList);
        }
        if (CollectionUtil.isNotEmpty(updateUserList)) {
            this.updateBatchById(updateUserList);
        }

    }

    /**
     * 用户主动加入群聊
     *
     * @param groupId
     * @param user
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean joinGroupUser(String groupId, Account user) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupId), MessageUtils.message("chat.chat.groupId.not.blank"));
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(groupId)))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        //群成员上限300人
        Long groupUserCount = 0L;
        //查看成员是否存在/申请
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getUserId, user.getId())
            .eq(ChatGroupUserEntity::getGroupId, groupId)
            .ne(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.TWO.getCode())
            .last("LIMIT 1");
        ChatGroupUserEntity userEntity = this.baseMapper.selectOne(wrapper);
        if (Objects.nonNull(userEntity)) {
            if (Objects.equals(GroupUserStatusEnum.ZERO.getCode(), userEntity.getStatus())) {
                if (Objects.equals(GroupExamineEnum.ZERO.getCode(), group.getExamine())) {
                    //群成员上限300人
                    groupUserCount = this.selectCountGroupUser(groupId);
                    if (Objects.nonNull(groupUserCount) && groupUserCount >= ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
                        CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
                    }
                    userEntity.setStatus(GroupUserStatusEnum.ONE.getCode());
                    //融云加群 -- 用户主动发起，成功则成功，失败则失败
                    boolean joinFlag = rongyunService.joinGroup(group.getGroupId(), group.getGroupName(), new String[]{userEntity.getUserId().toString()});
                    CommonErrors.BAD_REQUEST.check(joinFlag, MessageUtils.message("chat.group.rongyun.join.fail"));
                    //群若是禁言
                    if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                        //融云添加禁言
                        chatGroupMQService.sendProhibitionMessage(group, userEntity.getUserId().toString());
                    }
                    //添加群成员小灰条通知消息
                    chatGroupMessageService.sendAddMessage(user, group.getGroupId());
                    this.baseMapper.updateById(userEntity);
                } else {
                    //已申请
                    return Boolean.TRUE;
                }
            } else if (Objects.equals(GroupUserStatusEnum.ONE.getCode(), userEntity.getStatus())) {
                //已在群
                return Boolean.TRUE;
            }
        } else {
            //群成员上限300人
            groupUserCount = this.selectCountGroupUser(groupId);
            if (Objects.nonNull(groupUserCount) && groupUserCount >= ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
                CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
            }
            userEntity = new ChatGroupUserEntity(group.getGroupId(), user.getId(), "", "", "", "");
            userEntity.setCommon(GroupUserCommonEnum.QR_CODE.getCode());
            if (Objects.equals(GroupExamineEnum.ZERO.getCode(), group.getExamine())) {
                userEntity.setStatus(GroupUserStatusEnum.ONE.getCode());
                //融云加群 -- 用户主动发起，成功则成功，失败则失败
                boolean joinFlag = rongyunService.joinGroup(group.getGroupId(), group.getGroupName(), new String[]{userEntity.getUserId().toString()});
                CommonErrors.BAD_REQUEST.check(joinFlag, MessageUtils.message("chat.group.rongyun.join.fail"));
                //群若是禁言
                if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                    //融云添加禁言
                    chatGroupMQService.sendProhibitionMessage(group, userEntity.getUserId().toString());
                }
                //添加群成员小灰条通知消息
                chatGroupMessageService.sendAddMessage(user, group.getGroupId());
            } else {
                userEntity.setStatus(GroupUserStatusEnum.ZERO.getCode());
            }
            this.baseMapper.insert(userEntity);
        }

        if (Objects.nonNull(groupUserCount) && ChatConstants.CHAT_GROUP_AVATAR_COUNT > groupUserCount) {
            //生成新头像
            initGroupAvatar(group.getGroupId());
        }

        return Boolean.TRUE;
    }

    /**
     * 加入班级群
     *
     * @Title:
     * @MethodName: classJoinGroup
     * [classId, userId]
     * @Return java.lang.Boolean
     * @Exception
     * @Description:
     * @author: yyzhen
     * @date: 2023/4/7 10:19
     */
    @Override
    public Boolean classJoinGroup(Long classId, Long userId) {
        ChatGroupEntity groupEntity = chatGroupMapper.selectOne(wrapperClass(classId).last("LIMIT 1"));
        if (Objects.isNull(groupEntity)) {
            return Boolean.TRUE;
        }
        //获取需要添加的用户列表
        UserResultDTO user = R.as(userClient.findById(userId));
        if (Objects.isNull(user)) {
            return Boolean.TRUE;
        }
        //已入群
        ChatGroupUserResultDTO joined = selectByUserIdAndGroupId(userId, groupEntity.getGroupId());
        if (Objects.nonNull(joined)) {
            return Boolean.TRUE;
        }
        //待审核
        ChatGroupUserResultDTO pending = this.baseMapper.selectByGroupIdAndUserId(groupEntity.getGroupId(), userId, GroupUserStatusEnum.ZERO.getCode());
        ChatGroupUserEntity groupUser = new ChatGroupUserEntity(groupEntity.getGroupId(), user.getId(), "", "", "", "");
        groupUser.setStatus(GroupUserStatusEnum.ONE.getCode());
        groupUser.setCommon(GroupUserCommonEnum.UNKNOWN.getCode());
        //加入班级不计入审核，不校验上限，直接进入班级群
        //群成员数量
        Long groupUserCount = this.selectCountGroupUser(groupEntity.getGroupId());
        ClassStudentResultDTO studentResult = R.as(classStudentClient.findByStudentId(classId, userId));
        // 兼容老数据：当学生姓名和关系均为空时显示空字符串，而不是nullnull
        if (Objects.nonNull(studentResult)) {
            String studentName = Objects.isNull(studentResult.getStudentName()) ? "" : studentResult.getStudentName();
            String relationship = Objects.isNull(studentResult.getRelationship()) ? "" : studentResult.getRelationship();
            relationship = Objects.equals(ClassStudentRelationshipEnum.本人.getDescribe(), relationship) ? "" : studentResult.getRelationship();
            groupUser.setRenames(studentName + relationship);
        }
        if (Objects.isNull(pending)) {
            this.save(groupUser);
        } else {
            groupUser.setId(pending.getId());
            this.updateById(groupUser);
        }
        //融云加群
        chatGroupMQService.sendAddMessage(groupEntity, groupUser.getUserId().toString());
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), groupEntity.getAllForbiddenWords())) {
            //添加禁言
            chatGroupMQService.sendProhibitionMessage(groupEntity, groupUser.getUserId().toString());
        }
        if (Objects.nonNull(groupUserCount) && ChatConstants.CHAT_GROUP_AVATAR_COUNT > groupUserCount) {
            //生成新头像
            initGroupAvatar(groupEntity.getGroupId());
        }
        //添加群成员小灰条通知消息
        chatGroupMessageService.sendAddMessage(user, groupEntity.getGroupId());
        //添加到群成员列表
        return Boolean.TRUE;
    }

    /**
     * 移除群成员
     *
     * @param user
     * @param groupId 群组Id（融云）
     * @param dto     AddUserGroupCreateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeGroupUser(Account user, String groupId, RemoveUserGroupDTO dto) {
        ChatGroupEntity old = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(groupId)))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        // 数据验证
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupId), MessageUtils.message("chat.chat.groupId.not.blank"));
        // 角色验证 -- 操作人
        checkAdministration(user.getId(), groupId);
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getIds()), MessageUtils.message("chat.group.create.user.not.blank"));
        //查看需要被移除的成员
        List<ChatGroupUserEntity> list = selectEntityByUserIdAndGroupId(dto.getIds(), groupId);
        List<ChatGroupUserEntity> removeUser = new ArrayList<>();
        list.forEach(item -> {
            CommonErrors.BAD_REQUEST.check(!Objects.equals(user.getId(), item.getUserId()), MessageUtils.message("chat.group.user.remove.me"));
            CommonErrors.BAD_REQUEST.check(!Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), item.getLeaderFlag()), MessageUtils.message("chat.group.user.remove.leader"));
            removeUser.add(item);
        });
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(removeUser), MessageUtils.message("chat.group.create.user.not.blank"));

        List<String> userIds = new ArrayList<>();
        List<Long> groupUserIds = new ArrayList<>();
        removeUser.forEach(item -> {
            userIds.add(item.getUserId().toString());
            groupUserIds.add(item.getUserId());
        });
        //移出群成员小灰条通知消息
        List<UserResultDTO> userList = CollectionUtil.isNotEmpty(groupUserIds) ? R.as(userClient.findList(groupUserIds)) : new ArrayList<>();
        chatGroupMessageService.sendKickedMessage(user, userList, old.getGroupId());

        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), old.getAllForbiddenWords())) {
            //解除禁言
            chatGroupMQService.sendCancelProhibitionMessage(old, userIds);
        }
        //融云退群
        chatGroupMQService.sendQuitMessage(old, userIds);

        this.removeBatchByIds(removeUser);
        //生成新头像
        initGroupAvatar(groupId);
        return Boolean.TRUE;
    }

    /**
     * 移除群成员
     *
     * @param user
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeAdmin(Account user, RemoveUserGroupAdminDTO dto) {
        ChatGroupEntity old = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        ChatGroupUserEntity groupUser = selectEntityByUserIdAndGroupId(dto.getUserId(), dto.getGroupId());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupUser), MessageUtils.message("chat.group.create.user.not.blank"));
        CommonErrors.BAD_REQUEST.check(!Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), groupUser.getLeaderFlag()), MessageUtils.message("chat.group.user.remove.leader"));

        //移出群成员小灰条通知消息
        UserResultDTO userResultDTO = R.as(userClient.findById(dto.getUserId()));
        List<UserResultDTO> userResultList = new ArrayList<>();
        userResultList.add(userResultDTO);
        chatGroupMessageService.sendKickedMessage(user, userResultList, dto.getGroupId());

        List<String> userIds = new ArrayList<>();
        userIds.add(dto.getUserId().toString());
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), old.getAllForbiddenWords())) {
            //解除禁言
            chatGroupMQService.sendCancelProhibitionMessage(old, userIds);
        }
        //融云退群
        chatGroupMQService.sendQuitMessage(old, userIds);

        this.baseMapper.deleteById(groupUser);
        //生成新头像
        initGroupAvatar(dto.getGroupId());
        return Boolean.TRUE;
    }

    /**
     * 添加管理员
     *
     * @param dto AddGroupManageDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addGroupManage(Account user, AddGroupManageDTO dto) {
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        // 验证
        this.qunZhuYanZheng(user.getId(), dto.getGroupId(), dto);
        //管理员上限10人
        Long manageCount = this.selectCountManage(dto.getGroupId());
        if (Objects.nonNull(manageCount) && manageCount >= ChatConstants.CHAT_GROUP_MANAGE_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.manage.up.to.valid"));
        }
        // 获取被设为管理的群成员
        List<ChatGroupUserEntity> list = selectEntityByUserIdAndGroupId(dto.getUserIds(), dto.getGroupId());
        List<ChatGroupUserEntity> manageUser = new ArrayList<>();
        List<String> userIds = new ArrayList<>();
        list.forEach(item -> {
            if (Objects.equals(GroupUserLeaderFlagEnum.THREE.getCode(), item.getLeaderFlag())) {
                // 设置为管理
                item.setLeaderFlag(GroupUserLeaderFlagEnum.TWO.getCode());
                userIds.add(item.getUserId().toString());
                manageUser.add(item);
            }
        });
        //管理员上限10人
        manageCount = manageCount + manageUser.size();
        if (manageCount > ChatConstants.CHAT_GROUP_MANAGE_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.manage.up.to.valid"));
        }
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
            //解除禁言
            chatGroupMQService.sendCancelProhibitionMessage(group, userIds);
        }
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(manageUser), MessageUtils.message("chat.group.user.not.blank.not.manage"));

        //添加群管理小灰条通知消息
        List<Long> list2 = userIds.stream().map(Long::parseLong).collect(Collectors.toList());
        List<UserResultDTO> userList = CollectionUtil.isNotEmpty(list2) ? R.as(userClient.findList(list2)) : new ArrayList<>();
        chatGroupMessageService.sendAddManageMessage(user, userList, group.getGroupId());

        return this.updateBatchById(manageUser);
    }

    /**
     * 获取群管理员列表
     *
     * @param groupId 群id(融云)
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> findGroupManage(String groupId) {
        ChatGroupUserQueryDTO dto = new ChatGroupUserQueryDTO(groupId);
        dto.setLeaderFlag(GroupUserLeaderFlagEnum.TWO.getCode());
        dto.setStatus(GroupUserStatusEnum.ONE.getCode());
        return this.baseMapper.findGroupUserList(dto);
    }

    /**
     * 移除群管理员
     *
     * @param dto AddGroupManageDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeGroupManage(Account user, AddGroupManageDTO dto) {
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        // 验证
        this.qunZhuYanZheng(user.getId(), dto.getGroupId(), dto);
        // 获取被设为管理的群成员
        List<ChatGroupUserEntity> list = selectEntityByUserIdAndGroupId(dto.getUserIds(), dto.getGroupId());
        List<ChatGroupUserEntity> manageUser = new ArrayList<>();
        List<String> userIds = new ArrayList<>();
        list.forEach(item -> {
            if (Objects.equals(GroupUserLeaderFlagEnum.TWO.getCode(), item.getLeaderFlag())) {
                // 移除管理
                item.setLeaderFlag(GroupUserLeaderFlagEnum.THREE.getCode());
                userIds.add(item.getUserId().toString());
                manageUser.add(item);
            }
        });
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(manageUser), MessageUtils.message("chat.group.user.manage.not.blank"));
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
            //融云添加禁言
            chatGroupMQService.sendProhibitionMessage(group, userIds);
        }
        //移除群管理小灰条通知消息
        List<Long> list2 = userIds.stream().map(Long::parseLong).collect(Collectors.toList());
        List<UserResultDTO> userList = CollectionUtil.isNotEmpty(list2) ? R.as(userClient.findList(list2)) : new ArrayList<>();
        chatGroupMessageService.sendRemoveManageMessage(user, userList, group.getGroupId());
        return this.updateBatchById(manageUser);
    }

    /**
     * 获取群审核列表
     *
     * @param userId
     * @param groupId 群Id(融云)
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> getGroupManageAutoList(Long userId, String groupId) {
        // 角色验证
        checkAdministration(userId, groupId);
        ChatGroupUserQueryDTO dto = new ChatGroupUserQueryDTO(groupId);
        dto.setStatus(GroupUserStatusEnum.ZERO.getCode());
        dto.setLeaderFlag(GroupUserLeaderFlagEnum.THREE.getCode());
        return this.baseMapper.findGroupUserList(dto);
    }

    /**
     * 获取群成员列表
     *
     * @param dto
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> getUserList(ChatGroupUserQueryDTO dto) {
        dto.setStatus(GroupUserStatusEnum.ONE.getCode());
        return this.baseMapper.findGroupUserList(dto);
    }

    /**
     * 获取群成员列表 -- 分页
     *
     * @param pageable
     * @param query
     * @return
     */
    @Override
    @DS("slaver")
    public PageInfo<ChatGroupUserResultDTO> getUserPage(Param pageable, ChatGroupUserQueryDTO query) {
        IPage<ChatGroupUserResultDTO> pageData = this.baseMapper.findGroupUserPage(Pages.page(pageable), query);
        return Pages.convert(pageData);
    }

    @Override
    @DS("slaver")
    public PageInfo<ChatGroupUserAdminResultDTO> pageAdmin(Param pageable, ChatGroupUserAdminQueryDTO query) {
        //排序
        if (CollectionUtils.isEmpty(pageable.getSorts())) {
            pageable.setSorts(new ArrayList<>());
        }
        pageable.getSorts().add("gu.create_time,ASC");
        query.setGroupUserStatus(GroupUserStatusEnum.ONE.getCode());
        IPage<ChatGroupUserAdminResultDTO> pageData = this.baseMapper.pageAdmin(Pages.page(pageable), query);
        return Pages.convert(pageData);
    }

    /**
     * 退群
     *
     * @param userId
     * @param groupId 群Id(融云)
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean exitGroup(Long userId, String groupId) {
        ChatGroupUserResultDTO groupUser = selectByUserIdAndGroupId(userId, groupId);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupUser), MessageUtils.message("chat.group.user.is.not.existence"));
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(groupId)))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        return this.leaderExitGroup(group, groupUser);
    }

    /**
     * 退出班级群
     *
     * @Title:
     * @MethodName: classExitGroup
     * [classId, userId]
     * @Return java.lang.Boolean
     * @Exception
     * @Description:
     * @author: yyzhen
     * @date: 2023/3/30 10:25
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean classExitGroup(Long classId, Long userId) {
        ChatGroupEntity groupEntity = chatGroupMapper.selectOne(wrapperClass(classId).last("LIMIT 1"));
        if (Objects.isNull(groupEntity)) {
            return Boolean.TRUE;
        }
        ChatGroupUserResultDTO groupUser = selectByUserIdAndGroupId(userId, groupEntity.getGroupId());
        if (Objects.isNull(groupUser)) {
            return Boolean.TRUE;
        }
        return this.leaderExitGroup(groupEntity, groupUser);
    }

    /**
     * 添加消息免打扰关注成员
     *
     * @param userId
     * @param groupId 群Id(融云)
     * @param dto     AddUserGroupCreateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addGroupFollow(Long userId, String groupId, AddUserGroupCreateDTO dto) {

        ChatGroupUserEntity groupUser = selectEntityByUserIdAndGroupId(userId, groupId);
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getGroupUserIds()), MessageUtils.message("chat.group.create.user.not.blank"));
        ChatGroupUserQueryDTO query = new ChatGroupUserQueryDTO(groupId);
        query.setStatus(GroupUserStatusEnum.ONE.getCode());
        query.setUserIds(dto.getGroupUserIds());
        List<ChatGroupUserResultDTO> groupUserList = this.baseMapper.findGroupUserList(query);
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(groupUserList), MessageUtils.message("chat.group.create.user.not.blank"));
        groupUser.setFollow(StringUtils.join(dto.getGroupUserIds(), ","));
        return this.updateById(groupUser);
    }

    /**
     * 查询消息免打扰关注成员
     *
     * @param userId
     * @param groupId groupId
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> getGroupFollow(Long userId, String groupId) {
        return Optional.ofNullable(this.baseMapper.getGroupFollow(groupId, userId, GroupUserStatusEnum.ONE.getCode()))
            .orElse(new ArrayList<>());
    }

    /**
     * 根据群组ID获取群成员信息
     *
     * @param groupId
     * @param operationUserId
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> findGroupId(String groupId, Long operationUserId) {
        return this.baseMapper.findGroupId(groupId, operationUserId);
    }

    /**
     * 根据群成员用户ID获取群成员信息
     *
     * @param userList
     * @param type
     * @return
     */
    @DS("slaver")
    @Override
    public List<ChatGroupUserResultDTO> findReadUserList(List<Long> userList, int type) {
        if (CollectionUtil.isEmpty(userList) && Objects.equals(YesNoNumberEnum.YES.getCode(), type)) {
            return new ArrayList<>();
        }
        return this.baseMapper.findReadUserList(userList, type);
    }

    /**
     * 审核通过
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean examineUserToGroup(Account user, ChatGroupUsersExamineDTO dto) {
        ChatGroupUserEntity groupUser = this.baseMapper.selectById(dto.getId());
        //权限校验
        checkAdministration(user.getId(), groupUser.getGroupId());
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(groupUser.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        //群成员上限300人
        Long groupUserCount = this.selectCountGroupUser(group.getGroupId());
        if (Objects.nonNull(groupUserCount) && groupUserCount >= ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
        }
        //融云加群
        chatGroupMQService.sendAddMessage(group, groupUser.getUserId().toString());

        groupUser.setLeaderFlag(GroupUserLeaderFlagEnum.THREE.getCode());
        groupUser.setStatus(GroupUserStatusEnum.ONE.getCode());
        this.baseMapper.updateById(groupUser);

        if (Objects.nonNull(groupUserCount) && ChatConstants.CHAT_GROUP_AVATAR_COUNT > groupUserCount) {
            //生成新头像
            initGroupAvatar(group.getGroupId());
        }
        List<UserResultDTO> userResultList = new ArrayList<>();
        UserResultDTO resultDTO = R.as(userClient.findById(groupUser.getUserId()));
        userResultList.add(resultDTO);
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
            //融云添加禁言
            chatGroupMQService.sendProhibitionMessage(group, groupUser.getUserId().toString());
        }
        //添加群成员小灰条通知消息
        chatGroupMessageService.sendAddMessage(user, userResultList, group.getGroupId());
        return Boolean.TRUE;
    }

    /**
     * 审核通过 -- 批量
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean examineUserToGroup(Account user, ChatGroupUsersBatchExamineDTO dto) {
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getIds()), MessageUtils.message("chat.group.user.id.not.blank"));
        LambdaQueryWrapper<ChatGroupUserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ChatGroupUserEntity::getId, dto.getIds())
            .eq(ChatGroupUserEntity::getGroupId, dto.getGroupId());
        List<ChatGroupUserEntity> groupUsers = this.baseMapper.selectList(queryWrapper);
        //权限校验
        checkAdministration(user.getId(), dto.getGroupId());
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        //群成员上限300人
        Long groupUserCount = this.selectCountGroupUser(group.getGroupId());
        if (Objects.nonNull(groupUserCount) && groupUserCount >= ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
        }
        //在融云加入群
        List<String> userIds = new ArrayList<>();
        List<Long> groupUserIds = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        groupUsers.forEach(entity -> {
            userIds.add(entity.getUserId().toString());
            groupUserIds.add(entity.getUserId());
            ids.add(entity.getId());
        });
        //群成员上限300人
        long afterCount = groupUserCount + userIds.size();
        if (afterCount > ChatConstants.CHAT_GROUP_MEMBER_LIMIT) {
            CommonErrors.BAD_REQUEST.check(false, MessageUtils.message("chat.group.user.up.to.valid"));
        }

        //融云加群
        chatGroupMQService.sendAddMessage(group, userIds);

        LambdaUpdateWrapper<ChatGroupUserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ChatGroupUserEntity::getLeaderFlag, GroupUserLeaderFlagEnum.THREE.getCode())
            .set(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode())
            .in(ChatGroupUserEntity::getId, ids);
        this.update(updateWrapper);
        if (ChatConstants.CHAT_GROUP_AVATAR_COUNT > groupUserCount) {
            //生成新头像
            initGroupAvatar(group.getGroupId());
        }
        //群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
            //融云添加禁言
            chatGroupMQService.sendProhibitionMessage(group, userIds);
        }
        //添加群成员小灰条通知消息
        List<UserResultDTO> userList = CollectionUtil.isNotEmpty(groupUserIds) ? R.as(userClient.findList(groupUserIds)) : new ArrayList<>();
        chatGroupMessageService.sendAddMessage(user, userList, group.getGroupId());
        return Boolean.TRUE;
    }

    /**
     * 审核拒绝
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refuseUserToGroup(Account user, ChatGroupUsersExamineDTO dto) {
        ChatGroupUserEntity groupUser = this.baseMapper.selectById(dto.getId());
        //权限校验
        checkAdministration(user.getId(), groupUser.getGroupId());
        groupUser.setLeaderFlag(GroupUserLeaderFlagEnum.THREE.getCode());
        groupUser.setStatus(GroupUserStatusEnum.TWO.getCode());
        return this.baseMapper.updateById(groupUser) > 0;
    }

    /**
     * 审核拒绝 -- 批量
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refuseUserToGroup(Account user, ChatGroupUsersBatchExamineDTO dto) {
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getIds()), MessageUtils.message("chat.group.user.id.not.blank"));
        //权限校验
        checkAdministration(user.getId(), dto.getGroupId());
        LambdaUpdateWrapper<ChatGroupUserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ChatGroupUserEntity::getLeaderFlag, GroupUserLeaderFlagEnum.THREE.getCode())
            .set(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.TWO.getCode())
            .in(ChatGroupUserEntity::getId, dto.getIds());

        return this.update(updateWrapper);
    }

    /**
     * 通过用户ID和群组ID获取用户
     *
     * @param userId
     * @param groupId 群Id(融云)
     * @return
     */
    @Override
    public ChatGroupUserResultDTO selectByUserIdAndGroupId(Long userId, String groupId) {
        ChatGroupUserResultDTO result = this.baseMapper.selectByGroupIdAndUserId(groupId, userId, GroupUserStatusEnum.ONE.getCode());
        if (Objects.isNull(result)) {
            return null;
        }
        //二维码生成转化
        result.setGroupQrCodeStr(result.getGroupQrCode());
        return result;
    }

    private ChatGroupUserEntity selectEntityByUserIdAndGroupId(Long userId, String groupId) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getUserId, userId)
            .eq(ChatGroupUserEntity::getGroupId, groupId)
            .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode())
            .last("LIMIT 1");
        return Optional.ofNullable(this.baseMapper.selectOne(wrapper))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.user.is.not.existence")));
    }

    private List<ChatGroupUserEntity> selectEntityByUserIdAndGroupId(List<Long> userIds, String groupId) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.in(ChatGroupUserEntity::getUserId, userIds)
            .eq(ChatGroupUserEntity::getGroupId, groupId)
            .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode());
        return this.baseMapper.selectList(wrapper);
    }

    private void qunZhuYanZheng(Long userId, String groupId, AddGroupManageDTO dto) {
        ChatGroupUserResultDTO groupUser = selectByUserIdAndGroupId(userId, groupId);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupUser), MessageUtils.message("chat.group.user.is.not.existence"));
        CommonErrors.BAD_REQUEST.check(Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), groupUser.getLeaderFlag()), MessageUtils.message("chat.group.is.not.leader"));
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(groupId), MessageUtils.message("chat.chat.groupId.not.blank"));
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(dto.getUserIds()), MessageUtils.message("chat.group.create.user.not.blank"));
    }

    /**
     * 校验群管理员权限
     *
     * @param userId
     * @param groupId
     */
    @Override
    public ChatGroupUserEntity checkAdministration(Long userId, String groupId) {
        ChatGroupUserEntity groupUser = selectEntityByUserIdAndGroupId(userId, groupId);
        CommonErrors.BAD_REQUEST.check(
            Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), groupUser.getLeaderFlag())
                || Objects.equals(GroupUserLeaderFlagEnum.TWO.getCode(), groupUser.getLeaderFlag()), MessageUtils.message("chat.group.is.not.manage"));
        return groupUser;
    }


    /**
     * 获取群成员信息 -- 根据加群时间排序
     *
     * @param groupId
     * @param status
     * @param limit
     * @return
     */
    @Override
    public List<ChatGroupUserResultDTO> getGroupUserOrderByCreateTime(String groupId, Integer status, Integer limit) {
        return this.baseMapper.getGroupUserOrderByCreateTime(groupId, status, limit);
    }


    /**
     * 退出群聊
     *
     * @param group  群组信息
     * @param leader 退出成员
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean leaderExitGroup(ChatGroupEntity group, ChatGroupUserResultDTO leader) {
        if (Objects.isNull(group)) {
            return Boolean.TRUE;
        }
        if (Objects.isNull(leader)) {
            return Boolean.TRUE;
        }

        // 判断是否是群主
        if (Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), leader.getLeaderFlag())) {
            //群主退出群聊 -- 自动转让给加群最久的成员群主身份
            LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
            wrapper.eq(ChatGroupUserEntity::getGroupId, group.getGroupId())
                .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode())
                .ne(ChatGroupUserEntity::getLeaderFlag, GroupUserLeaderFlagEnum.ONE.getCode())
                .orderByAsc(ChatGroupUserEntity::getCreateTime)
                .last("LIMIT 1");
            ChatGroupUserEntity newLeader = this.baseMapper.selectOne(wrapper);
            // 判断是否有群管理员 (如果 没有则直接解散 有则进行群转让-转让给第一个设置的群管理员)
            if (Objects.isNull(newLeader)) {
                //解散群
                group.setStatus(GroupStatusEnum.TWO.getCode());
                chatGroupMapper.updateById(group);
                //群若是禁言 则解除群禁言
                if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                    //解除禁言
                    chatGroupMQService.sendCancelProhibitionMessage(group, leader.getUserId().toString());
                }
                //融云解散群组
                chatGroupMQService.sendDismissMessage(group);
                //退出群
                this.deleteById(leader.getId());
            } else {
                //转让时，群若是禁言
                if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())
                    && Objects.equals(GroupUserLeaderFlagEnum.THREE.getCode(), newLeader.getLeaderFlag())) {
                    //解除新群主禁言、
                    chatGroupMQService.sendCancelProhibitionMessage(group, newLeader.getUserId().toString());
                }
                //有群成员 -- 转让群主身份、群主退群
                newLeader.setLeaderFlag(GroupUserLeaderFlagEnum.ONE.getCode());
                group.setUserId(newLeader.getUserId());
                chatGroupMapper.updateById(group);
                // 保存成员身份修改
                this.baseMapper.updateById(newLeader);
                //退出群
                this.deleteById(leader.getId());
                //生成新头像
                initGroupAvatar(group.getGroupId());
                //退出群组小灰条通知消息
                UserResultDTO userResultDTO = R.as(userClient.findById(leader.getUserId()));
                chatGroupMessageService.sendQuitMessage(userResultDTO, leader.getGroupId(), newLeader.getUserId().toString());
                //融云退群
                chatGroupMQService.sendQuitMessage(group, leader.getUserId().toString());
            }
        } else {
            //群若是禁言
            if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
                //解除禁言、
                chatGroupMQService.sendCancelProhibitionMessage(group, leader.getUserId().toString());
            }
            //退出群
            this.deleteById(leader.getId());
            //生成新头像
            initGroupAvatar(group.getGroupId());
            //退出群组小灰条通知消息
            UserResultDTO userResultDTO = R.as(userClient.findById(leader.getUserId()));
            chatGroupMessageService.sendQuitMessage(userResultDTO, leader.getGroupId(), null);
            //融云退群
            chatGroupMQService.sendQuitMessage(group, leader.getUserId().toString());
        }
        return Boolean.TRUE;
    }

    /**
     * 设为群主
     *
     * @param user
     * @param dto
     * @return
     */
    @Override
    public Boolean setLeaderAdmin(Account user, SetUserGroupAdminDTO dto) {
        ChatGroupEntity group = Optional.ofNullable(chatGroupMapper.selectOne(wrapper(dto.getGroupId())))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("chat.group.group.not.blank")));
        ChatGroupUserResultDTO shiftUser = selectByUserIdAndGroupId(dto.getUserId(), dto.getGroupId());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(shiftUser), MessageUtils.message("chat.group.create.user.not.blank"));
        if (Objects.equals(GroupUserLeaderFlagEnum.ONE.getCode(), shiftUser.getLeaderFlag())) {
            return Boolean.TRUE;
        }
        ChatGroupUserEntity mainUser = selectLeader(dto.getGroupId());

        //转让时，群若是禁言
        if (Objects.equals(GroupAllForbiddenWordsEnum.ONE.getCode(), group.getAllForbiddenWords())) {
            if (Objects.nonNull(mainUser)) {
                //解除新群主禁言
                chatGroupMQService.sendCancelProhibitionMessage(group, shiftUser.getUserId().toString());
            }
            //添加原群主禁言
            chatGroupMQService.sendProhibitionMessage(group, mainUser.getUserId().toString());
        }
        if (Objects.nonNull(mainUser)) {
            ChatGroupUserEntity userEntity2 = new ChatGroupUserEntity();
            userEntity2.setId(mainUser.getId());
            userEntity2.setLeaderFlag(GroupUserLeaderFlagEnum.THREE.getCode());
            this.baseMapper.updateById(userEntity2);
        }
        ChatGroupUserEntity userEntity1 = new ChatGroupUserEntity();
        userEntity1.setId(shiftUser.getId());
        userEntity1.setLeaderFlag(GroupUserLeaderFlagEnum.ONE.getCode());
        this.baseMapper.updateById(userEntity1);

        group.setUserId(shiftUser.getUserId());
        chatGroupMapper.updateById(group);

        //转让群主小灰条通知消息
        ChatGroupUserResultDTO mainUserDto = chatGroupUserConvert.convert(mainUser);
        if (Objects.nonNull(mainUserDto)) {
            UserResultDTO resultDTO = R.as(userClient.findById(mainUser.getUserId()));
            if (Objects.nonNull(user)) {
                mainUserDto.setNickname(resultDTO.getNickname());
            }
        }
        chatGroupMessageService.sendShiftLeaderMessage(shiftUser, mainUserDto, group.getGroupId());

        return Boolean.TRUE;
    }

    /**
     * 正常状态的群
     *
     * @param groupId
     * @return
     */
    private LambdaQueryWrapper<ChatGroupEntity> wrapper(String groupId) {
        LambdaQueryWrapper<ChatGroupEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupEntity::getGroupId, groupId)
            .eq(ChatGroupEntity::getStatus, GroupStatusEnum.ONE.getCode())
            .last("LIMIT 1");
        return wrapper;
    }

    /**
     * 查询群成员信息
     *
     * @param groupId
     * @param statusList
     * @return
     */
    private LambdaQueryWrapper<ChatGroupUserEntity> userWrapper(String groupId, List<Integer> statusList) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getGroupId, groupId)
            .in(ChatGroupUserEntity::getStatus, statusList);
        return wrapper;
    }

    /**
     * 查询班级群
     *
     * @param classId
     * @return
     */
    private LambdaQueryWrapper<ChatGroupEntity> wrapperClass(Long classId) {
        LambdaQueryWrapper<ChatGroupEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupEntity::getClassId, classId)
            .eq(ChatGroupEntity::getStatus, GroupStatusEnum.ONE.getCode());
        return wrapper;
    }

    /**
     * 获取群主
     *
     * @param groupId
     * @return
     */
    private ChatGroupUserEntity selectLeader(String groupId) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getGroupId, groupId)
            .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode())
            .eq(ChatGroupUserEntity::getLeaderFlag, GroupUserLeaderFlagEnum.ONE.getCode())
            .last("LIMIT 1");
        return this.baseMapper.selectOne(wrapper);
    }


    /**
     * 查找群管理数量
     *
     * @param groupId
     * @return
     */
    private Long selectCountManage(String groupId) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getGroupId, groupId)
            .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode())
            .eq(ChatGroupUserEntity::getLeaderFlag, GroupUserLeaderFlagEnum.TWO.getCode());
        return this.baseMapper.selectCount(wrapper);
    }

    /**
     * 查找群成员数量
     *
     * @param groupId
     * @return
     */
    private Long selectCountGroupUser(String groupId) {
        LambdaQueryWrapper<ChatGroupUserEntity> wrapper = Queries.lambda();
        wrapper.eq(ChatGroupUserEntity::getGroupId, groupId)
            .eq(ChatGroupUserEntity::getStatus, GroupUserStatusEnum.ONE.getCode());
        return this.baseMapper.selectCount(wrapper);
    }

    /**
     * 群头像采用加群最久的两个用户头像
     *
     * @param groupId
     */
    private void initGroupAvatar(String groupId) {
        List<ChatGroupUserResultDTO> list = this.baseMapper.getGroupUserOrderByCreateTime(groupId, GroupUserStatusEnum.ONE.getCode(), 2);
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        String avatar = null;
        if (list.size() > 1) {
            try {
                String defaultAvatar = R.as(sysConfigClient.getConfigKey(ConfigKeyConstants.SYS_DEFAULT_AVATAR));
                String groupImg = groupId + "groupimg" + System.currentTimeMillis();
                avatar = ImageUtil.composite2(list.get(0).getAvatar(), list.get(1).getAvatar(), groupImg, defaultAvatar);
            } catch (Exception | Error e) {
                avatar = list.get(0).getAvatar();
            }
        } else if (list.size() == 1) {
            avatar = list.get(0).getAvatar();
        }

        if (StringUtils.isNotEmpty(avatar)) {
            LambdaUpdateWrapper<ChatGroupEntity> update = new LambdaUpdateWrapper<>();
            update.set(ChatGroupEntity::getAvatar, avatar)
                .eq(ChatGroupEntity::getGroupId, groupId);
            chatGroupMapper.update(null, update);
        }
    }

}
